﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RoguelikeLib.Maps;

namespace RoguelikeLib
{
    class StandardDungeon
    {
        private static int MinRooms = 3;
        private const int MaxRooms = 10;

        public const int MinRoomHeight = 5;
        public const int MinRoomWidth = 5;

        public List<Room> Rooms = new List<Room>();
        public Tile[][] Map = new Tile[40][];
        private int _numberOfRooms;
        public RObjects FillMaterial = RObjects.StoneWall;

        public StandardDungeon()
        {
            MinRooms = Game.Roll(3, 1, 4);
            //MinRooms = 1;
        }


        public void Debug()
        {
            
        }

        public void GenerateMap()
        {
            // Fill map
            for (int i = 0; i < Map.Length; i++)
            {
                var tileRow = new Tile[80];
                Map[i] = tileRow;
                for (int index = 0; index < tileRow.Length; index++)
                    tileRow[index] = new Tile() { Type = RObjects.BaseMaterial };
            }
            // Create first room

            //int roomHeight = Math.Max(MinRoomHeight, Game.Roll(4, 0, 3));
            //int roomWidth = Math.Max(MinRoomWidth, Game.Roll(5, 0, 3));
            //var bottom = top + roomHeight;
            //var right = left + roomWidth;
            bool firstRoomAdded = false;
            Room firstRoom = null;
            //Carving firstRoom =null;
            while (!firstRoomAdded)
            {
                var x = Game.RNG.Next(Game.MapWidth);
                var y = Game.RNG.Next(Game.MapHeight);
                //firstRoom = Carving.CreateRoom(this, x, y);
                firstRoom = Room.CreateRoom(this, x, y);
                if (firstRoom == null)
                    continue;
                firstRoom.Features.Add(new Room.Feature()
                {
                    Type = RObjects.StairsDown,
                    X = Game.Roll(1, firstRoom.Left + 1, firstRoom.Right - 1),
                    Y = Game.Roll(1, firstRoom.Top + 1, firstRoom.Bottom - 1)
                });
                //var firstRoom = new Carving(this, left, top, right, bottom, Carving.CarvingTypes.Room);
                if (!firstRoom.AddToMap())
                    throw new Exception("This should never happen!!!");

                firstRoomAdded = true;
            }
            firstRoom.AddRooms(1);
            while (Rooms.Count < MinRooms)
            {
                var room = Rooms[Game.Roll(1, 0, Rooms.Count - 1)];
                room.AddRooms();
            }
            foreach (var corridor in Rooms.SelectMany(r => r.Corridors))
            {
                foreach (var room in Rooms)
                {
                    List<Point> points;
                    if (corridor.IntersectsWithRoom(room, out points))
                    {
                        foreach (var point in points)
                        {
                            var door = new Room.Door() {Type = Room.Door.DoorType.Fire, X = point.X, Y = point.Y};
                            room.Doors.Add(door);
                            door.AddToMap(this);
                        }
                    }
                }
            }
            for (int i = 0; i < Map.Length; i++)
            {
                var tileRow = Map[i];
                for (int index = 0; index < tileRow.Length; index++)
                    if (tileRow[index].Type == RObjects.BaseMaterial)
                        tileRow[index] = new Tile() { Type = RObjects.StoneWall };
            }
            //KeepCarving(firstRoom.AddRooms());

        }

        //private void KeepCarving(List<Carving> carvings )
        //{
        //    foreach (var carving in carvings)
        //        KeepCarving(carving.AddRandomCarvings());
        //}
    }
}
